(function (root, factory) {
  if (typeof module === "object" && typeof module.exports === "object") {
    // 是commonjs模块规范，nodejs环境
    module.exports = factory();
  } else if (typeof define === "function" && define.amd) {
    // 是AMD模块规范，如require.js
    define(factory);
  } else if (typeof define === "function" && define.cmd) {
    // CMD模块规范，如sea.js
    define(function (require, exports, module) {
      module.exports = factory();
    });
  } else {
    // 没有模块环境，直接挂载在全局对象上
    root.MusicLyricModule = factory();
  }
})(this, function () {
  const style = `
    .list-lyric {
      --lyric-item-color: gray;
      --lyric-item-color-active: white;

      flex: 1;
      list-style: none;

      overflow: auto;
      scroll-behavior: smooth;
      transition: 0.3s linear;

      padding: 0;
      margin: 0;
      height: 24em;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
      gap: 1em;
    }
    .list-lyric::-webkit-scrollbar {
      background-color: #aaa;
      border-radius: 0.25rem;
    }
    .list-lyric::-webkit-scrollbar-thumb {
      background-color: #666;
      border-radius: 0.25rem;
    }
    .list-lyric::-webkit-scrollbar-button {
      display: none;
    }

    .list-lyric .list-item {
      user-select: none;
      transition: 0.2s;
      color: var(--lyric-item-color);
    }

    .list-lyric .list-item.active {
      color: var(--lyric-item-color-active);
      transform: scale(1.25);
    }
  `;
  const styleElement = document.createElement("style");
  styleElement.innerHTML = style;
  document.head.appendChild(styleElement);

  /**
   * 解析歌词
   * @param {string} lyric
   * @returns {Array<{time: number, text: string}>}
   */
  function parseLyric(lyric) {
    return lyric.split("\n").map((item) => {
      const [timeString, text] = item.split("]");
      const [minute, second] = timeString.slice(1).split(":");
      const time = parseInt(minute) * 60 + parseInt(second);
      return {
        time,
        text: text.trim(),
      };
    });
  }
  /**
   * 寻找当前播放时间对应的歌词索引
   * @param {Array<{time: number, text: string}>} lyricList
   * @param {number} time
   * @returns {number}
   */
  function findLyricIndex(lyricList, time) {
    if (!lyricList || lyricList.length == 0) {
      return -1;
    }
    for (let i = 0; i < lyricList.length; i++) {
      const item = lyricList[i];
      // 出现的第一个时间大于当前时间，返回上一个索引
      if (time < item.time) {
        return i - 1;
      }
    }
    return -1;
  }

  /**
   * 滚动歌词列表
   * @param {HTMLUListElement} listElement
   * @param {number} itemIndex
   */
  function scrollListElement(listElement, itemIndex) {
    const li = listElement.querySelector(".active");
    if (li) {
      li.classList.remove("active");
    }
    if (itemIndex < 0) {
      listElement.scrollBy(0, 0);
      return;
    }
    const currentElement = listElement.children[itemIndex];
    currentElement.classList.add("active");
    const listRectangle = listElement.getBoundingClientRect();
    const itemRectangle = currentElement.getBoundingClientRect();
    const offset =
      itemRectangle.top - listRectangle.top - listRectangle.height / 2.5;
    listElement.scrollBy(0, offset);
  }
  /**
   * 滚动歌词列表
   * @param {HTMLElement} listElement
   * @param {Array<{time: number, text: string}>} lyricList
   * @param {number} time
   */
  function scrollListElementByTime(listElement, lyricList, time) {
    const index = findLyricIndex(lyricList, time);
    scrollListElement(listElement, index);
  }

  function createLyricListElement(lyricList) {
    const ul = document.createElement("ul");
    ul.classList.add("list-lyric");
    ul.classList.add("lyric-list");
    lyricList.forEach((item) => {
      const li = document.createElement("li");
      li.className = "list-item";
      li.textContent = item.text;
      li.time = item.time;
      li.dataset.time = item.time;

      li.onmouseout = () => {
        li.style.cursor = "default";
      };
      ul.appendChild(li);
    });
    return ul;
  }

  /**
   * 歌词类
   */
  function MusicLyric(lyric = "") {
    this.init(lyric);
  }
  /**
   * 初始化歌词列表
   * @param {string} lyric
   */
  MusicLyric.prototype.init = function (lyric) {
    this.lyricList = this.parseLyric(lyric);
    // console.log("Initialized lyric list:", this.lyricList);
  };
  /**
   * 解析歌词文本
   * @returns {Array<{time: number, text: string}>}
   */
  MusicLyric.prototype.parseLyric = parseLyric;
  /**
   * 寻找当前播放时间对应的歌词索引
   * @param {number} time
   * @returns {number}
   */
  MusicLyric.prototype.findLyricIndex = function (time) {
    return findLyricIndex(this.lyricList, time);
  };
  /**
   * 创建歌词列表元素
   * @returns {HTMLUListElement}
   */
  MusicLyric.prototype.createLyricListElement = function () {
    return createLyricListElement(this.lyricList);
  };

  MusicLyric.prototype.scrollListElement = function (lyricListElement, index) {
    scrollListElement(lyricListElement, index);
  };
  /**
   * 滚动歌词列表元素
   * @param { HTMLElement } lyricListElement
   * @param { number } time
   */
  MusicLyric.prototype.scrollListElementByTime = function (
    lyricListElement,
    time,
  ) {
    scrollListElementByTime(lyricListElement, this.lyricList, time);
  };

  return {
    MusicLyric,
    /**
     * 创建一个与 audioElement 相关联的动态歌词列表元素
     * @param {HTMLAudioElement} audioElement
     * @param {string} lyric
     */
    createDynamicLyricListElement(audioElement, lyric) {
      const musicLyric = new MusicLyric(lyric);
      const listElement = musicLyric.createLyricListElement();
      for (const li of listElement.children) {
        li.onmouseover = () => {
          if (!audioElement.paused) {
            li.style.cursor = "pointer";
          }
        };
        li.onclick = () => {
          audioElement.currentTime = li.time || li.dataset.time;
        };
      }

      let currentIndex = -1;
      audioElement.ontimeupdate = (e) => {
        /** @type {HTMLAudioElement} */
        const audioElement = e.target;
        if (audioElement.paused) {
          return;
        }
        const currentTime = audioElement.currentTime;
        // 在一句歌词来临前不滚动
        const index = musicLyric.findLyricIndex(currentTime);
        if (index !== currentIndex) {
          currentIndex = index;
          musicLyric.scrollListElement(listElement, index);
        }
      };
      return listElement;
    },
  };
});
